{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "from torch import nn\n",
    "from torchvision import datasets, transforms"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "transform = transforms.Compose([transforms.ToTensor(),\n",
    "                              transforms.Normalize((0.5,), (0.5,)),\n",
    "                              ])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "batch_size = 64"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "trainset = datasets.FashionMNIST('Fashion_MNIST/', download=True, train=True, transform=transform)\n",
    "trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True)\n",
    "\n",
    "# Download and load the test data\n",
    "testset = datasets.FashionMNIST('Fashion_MNIST/', download=True, train=False, transform=transform)\n",
    "testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "class FashionNetwork(nn.Module):\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "        self.hidden1 = nn.Linear(784, 256)\n",
    "        self.hidden2 = nn.Linear(256, 128)\n",
    "        self.output = nn.Linear(128, 10)\n",
    "        self.softmax = nn.Softmax(dim=1)\n",
    "        self.activation = nn.ReLU()\n",
    "    def forward(self, x):\n",
    "        x = self.hidden1(x)\n",
    "        x = self.activation(x)\n",
    "        x = self.hidden2(x)\n",
    "        x = self.activation(x)\n",
    "        x = self.output(x)\n",
    "        output = self.softmax(x)\n",
    "        return output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = FashionNetwork()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "FashionNetwork(\n",
      "  (hidden1): Linear(in_features=784, out_features=256, bias=True)\n",
      "  (hidden2): Linear(in_features=256, out_features=128, bias=True)\n",
      "  (output): Linear(in_features=128, out_features=10, bias=True)\n",
      "  (softmax): Softmax(dim=1)\n",
      "  (activation): ReLU()\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "print(model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Parameter containing:\n",
       "tensor([[-0.0152, -0.0040, -0.0269,  ...,  0.0049,  0.0136,  0.0135],\n",
       "        [ 0.0242, -0.0256, -0.0206,  ...,  0.0194, -0.0333, -0.0030],\n",
       "        [-0.0094, -0.0268, -0.0239,  ..., -0.0052,  0.0211,  0.0051],\n",
       "        ...,\n",
       "        [-0.0136, -0.0026,  0.0006,  ...,  0.0100, -0.0222,  0.0064],\n",
       "        [ 0.0030, -0.0023, -0.0167,  ...,  0.0339, -0.0322, -0.0253],\n",
       "        [-0.0255, -0.0146, -0.0210,  ..., -0.0321,  0.0280,  0.0298]],\n",
       "       requires_grad=True)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.hidden1.weight"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "class FashionNetwork(nn.Module):\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "        self.hidden1 = nn.Linear(784, 256)\n",
    "        self.hidden2 = nn.Linear(256, 128)\n",
    "        self.output = nn.Linear(128, 10)\n",
    "        self.log_softmax = nn.LogSoftmax(dim=1)\n",
    "        self.activation = nn.ReLU()\n",
    "    def forward(self, x):\n",
    "        x = self.hidden1(x)\n",
    "        x = self.activation(x)\n",
    "        x = self.hidden2(x)\n",
    "        x = self.activation(x)\n",
    "        x = self.output(x)\n",
    "        output = self.log_softmax(x)\n",
    "        return output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = FashionNetwork()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "FashionNetwork(\n",
       "  (hidden1): Linear(in_features=784, out_features=256, bias=True)\n",
       "  (hidden2): Linear(in_features=256, out_features=128, bias=True)\n",
       "  (output): Linear(in_features=128, out_features=10, bias=True)\n",
       "  (log_softmax): LogSoftmax()\n",
       "  (activation): ReLU()\n",
       ")"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "criterion = nn.NLLLoss()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "NLLLoss()"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "criterion"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch import optim"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "optimizer = optim.Adam(model.parameters())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'lr': 0.001,\n",
       " 'betas': (0.9, 0.999),\n",
       " 'eps': 1e-08,\n",
       " 'weight_decay': 0,\n",
       " 'amsgrad': False}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "optimizer.defaults"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "optimizer = optim.Adam(model.parameters(), lr=3e-3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'lr': 0.003,\n",
       " 'betas': (0.9, 0.999),\n",
       " 'eps': 1e-08,\n",
       " 'weight_decay': 0,\n",
       " 'amsgrad': False}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "optimizer.defaults"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "epoch = 10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training loss: 0.4982\n",
      "Training loss: 0.3865\n",
      "Training loss: 0.3471\n",
      "Training loss: 0.3281\n",
      "Training loss: 0.3163\n",
      "Training loss: 0.3006\n",
      "Training loss: 0.2854\n",
      "Training loss: 0.2805\n",
      "Training loss: 0.2672\n",
      "Training loss: 0.2648\n"
     ]
    }
   ],
   "source": [
    "for _ in range(epoch):\n",
    "    running_loss = 0\n",
    "    for image, label in trainloader:\n",
    "        optimizer.zero_grad()\n",
    "        image = image.view(image.shape[0],-1)\n",
    "        pred = model(image)\n",
    "        loss = criterion(pred, label)\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "        running_loss += loss.item()\n",
    "    else:\n",
    "        print(f'Training loss: {running_loss/len(trainloader):.4f}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.tensor([[1]]).item()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "class FashionNetwork(nn.Module):\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "        self.hidden1 = nn.Linear(784, 256)\n",
    "        self.hidden2 = nn.Linear(256, 128)\n",
    "        self.output = nn.Linear(128, 10)\n",
    "        self.log_softmax = nn.LogSoftmax()\n",
    "        self.activation = nn.ReLU()\n",
    "        self.drop = nn.Dropout(p=0.25)\n",
    "    def forward(self, x):\n",
    "        x = self.hidden1(x)\n",
    "        x = self.activation(x)\n",
    "        x = self.drop(x)\n",
    "        x = self.hidden2(x)\n",
    "        x = self.activation(x)\n",
    "        x = self.drop(x)\n",
    "        x = self.output(x)\n",
    "        output = self.log_softmax(x)\n",
    "        return output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = FashionNetwork()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "FashionNetwork(\n",
       "  (hidden1): Linear(in_features=784, out_features=256, bias=True)\n",
       "  (hidden2): Linear(in_features=256, out_features=128, bias=True)\n",
       "  (output): Linear(in_features=128, out_features=10, bias=True)\n",
       "  (log_softmax): LogSoftmax()\n",
       "  (activation): ReLU()\n",
       "  (drop): Dropout(p=0.25, inplace=False)\n",
       ")"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch.nn.functional as F"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "class FashionNetwork(nn.Module):\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "        self.hidden1 = nn.Linear(784,256)\n",
    "        self.hidden2 = nn.Linear(256,128)\n",
    "        self.output = nn.Linear(128,10)\n",
    "        \n",
    "        \n",
    "    def forward(self,x):\n",
    "        x = F.relu(self.hidden1(x))\n",
    "        x = F.relu(self.hidden2(x))\n",
    "        x = F.log_softmax(self.output(x))\n",
    "        return x\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
